﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zcu.PanelComposer.ViewModels.Core;
using Zcu.PanelComposer.Interfaces;
using System.ComponentModel.Composition;
using System.Windows.Media;
using Zcu.PanelComposer.Models.Model;
using Caliburn.Micro;
using Microsoft.Win32;
using System.Windows.Controls;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows;
using Zcu.PanelComposer.ViewModels.Events;
using System.ComponentModel;

namespace Zcu.PanelComposer.ViewModels.Pages
{
    /// <summary>
    /// ViewModel pro kresleni na zdi.
    /// </summary>
    [Export(typeof(IModule))]
    public class PanelViewModel : NavigateScreen
    {
        #region Fields

        /// <summary>
        /// Reference na logger.
        /// </summary>
        private readonly ILog _log = LogManager.GetLog(typeof(PanelViewModel));

        /// <summary>
        /// Reference na aktivni projekt.
        /// </summary>
        private Project _SelectedProject;

        /// <summary>
        /// Reference na kolekci bodu polygonu
        /// </summary>
        private PointCollection _PolyCollection;

        /// <summary>
        /// Vyska budovy.
        /// </summary>
        private int _Height;

        /// <summary>
        /// Pocet pater.
        /// </summary>
        private int _Floors;

        /// <summary>
        /// Serializovany XAML.
        /// </summary>
        private string _Serializable;

        /// <summary>
        /// nazev obrazku po importu.
        /// </summary>
        private const string ImageNameConst = "Import";

        #endregion // Fields

        #region Properties

        /// <summary>
        /// Gets the repository.
        /// </summary>
        [Import]
        public IRepository Repository { get; private set; }

       
        public Zcu.PanelComposer.Models.Model.Drawing Drawing { get; set; }

        private int _ForceRead;
        public int ForceRead
        {
            get { return _ForceRead; }
            set
            {
                if (_ForceRead != value) _ForceRead = value;
                NotifyOfPropertyChange(() => ForceRead);
            }
        }


        /// <summary>
        /// Reference na aktivni projekt.
        /// </summary>
        public Project SelectedProject
        {
            get { return _SelectedProject; }
            set
            {
                if (_SelectedProject != value) _SelectedProject = value;
                NotifyOfPropertyChange(() => SelectedProject);
            }
        }

        /// <summary>
        /// Gets or sets the poly collection.
        /// </summary>
        /// <value>
        /// The poly collection.
        /// </value>
        public PointCollection PolyCollection
        {
            get { return _PolyCollection; }
            set
            {
                if (_PolyCollection != value)
                    _PolyCollection = value;
                NotifyOfPropertyChange(() => PolyCollection);
            }
        }

        /// <summary>
        /// Gets or sets the height.
        /// </summary>
        /// <value>
        /// The height.
        /// </value>
        public int Height
        {
            get { return _Height; }
            set
            {
                if (_Height != value) _Height = value;
                NotifyOfPropertyChange(() => Height);
            }
        }

        /// <summary>
        /// Gets or sets the floors.
        /// </summary>
        /// <value>
        /// The floors.
        /// </value>
        public int Floors
        {
            get { return _Floors; }
            set
            {
                if (_Floors != value) _Floors = value;
                NotifyOfPropertyChange(() => Floors);
            }
        }

        /// <summary>
        /// Gets or sets the serializable.
        /// </summary>
        /// <value>
        /// The serializable.
        /// </value>
        public string Serializable
        {
            get { return _Serializable; }
            set
            {
                if (_Serializable != value) _Serializable = value;
                NotifyOfPropertyChange(() => Serializable);
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PanelViewModel"/> class.
        /// </summary>
        public PanelViewModel()
        {
            /// todo do resources
            DisplayName = "Panel drawer";
            ModuleName = PageNames.Panel;
            Order = 7;
            MenuVisible = false;
        }

        #endregion // Constructor

        #region Overrided methods

        /// <summary>
        /// Udalost, ktera je volana hned po vytvoreni screenu.
        /// </summary>
        public override void OnReconstruct()
        {
            base.OnReconstruct();

            // registrace zachycovani udalosti zmeny projektu.
            EventAggregator.Subscribe(this);
        }

        /// <summary>
        /// Called when activating.
        /// </summary>
        protected override void OnActivate()
        {
            base.OnActivate();

            if (Context != null && Context is Project)
            {
                SelectedProject = (Project)Context;
            }
            else
            {
                throw new Exception("Context is empty or not Project type");
            }

            // vyresetovani promenne
            Drawing = null;

            // nacteni dat
            LoadData();
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Resets the action.
        /// </summary>
        public void ResetAction()
        {
            Serializable = null;
        }

        /// <summary>
        /// Akce, vyvolana stiskem tlacitka "Draw base".
        /// </summary>
        public void BackAction()
        {
            Navigate(this.SourcePage);
        }

        /// <summary>
        /// Exports the action.
        /// </summary>
        public void ExportAction()
        {
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = "layer"; // Default file name 
            dlg.DefaultExt = ".png"; // Default file extension 
            dlg.Filter = "Portable Network Graphics (.png)|*.png"; // Filter files by extension 

            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                // upozorneni View, ze budeme cist
                ForceRead = DateTime.Now.Millisecond;

                Canvas canvas = Utils.DeserializableCanvas(Serializable);
                string filename = dlg.FileName;

                int i = 0;
                while (canvas.Children.Count > 0)
                {
                    foreach (System.Windows.UIElement ele in canvas.Children)
                    {
                        if(Canvas.GetZIndex(ele) != i)
                        {
                            ele.Visibility = System.Windows.Visibility.Hidden;
                        }
                    }
                    Utils.SaveCanvas(canvas, 96, filename.Replace(".png", string.Format("_{0}.png", i.ToString("00"))));

                    List<System.Windows.UIElement> rem = new List<System.Windows.UIElement>();
                    foreach (System.Windows.UIElement ele in canvas.Children)
                    {
                        if (Canvas.GetZIndex(ele) == i)
                        {
                            rem.Add(ele);
                        }
                        else
                        {
                            ele.Visibility = System.Windows.Visibility.Visible;
                        }
                    }

                    foreach (var ele in rem)
                    {
                        canvas.Children.Remove(ele);
                    }

                    i++;
                }

                MessageBox.Show("Export is completed.", "Information dialog", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        public void ImportAction()
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.FileName = "layer"; // Default file name 
            dlg.DefaultExt = ".png"; // Default file extension 
            dlg.Filter = "Portable Network Graphics (.png)|*.png"; // Filter files by extension 

            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                // upozorneni View, ze budeme cist
                ForceRead = DateTime.Now.Millisecond;

                Drawing = FileHelper.SaveDrawing(Repository, dlg.FileName);
                if (Drawing == null) return;

                var canvas = Utils.DeserializableCanvas(Serializable);
                if (canvas == null) return;

                Image img = null;
                foreach (UIElement item in canvas.Children)
                {
                    // hledani obrazu 
                    if (item is Image && ((Image)item).Name == ImageNameConst)
                    {
                        img = (Image)item;
                    }
                }

                BitmapImage bimg = new BitmapImage(new Uri(FileHelper.GetDrawingPath(Drawing)));
                if (img == null)
                {
                    // vytvorime novy element
                    img = new Image();
                    img.Name = ImageNameConst;
                    // pridani do platna
                    Canvas.SetZIndex(img, 0);
                    canvas.Children.Add(img);
                }
                // zmena zdroje na novy obrazek
                img.Source = bimg;

                // zpetna serializace
                Serializable = Utils.SerializableCanvas(canvas);

                MessageBox.Show("Import is completed.", "Information dialog", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Akce, vyvolana stiskem tlacitka "Rename project".
        /// </summary>
        public void SaveAction()
        {
            // vykresy
            if (Drawing != null)
            {
                // pridani do DB
                Repository.Add<Zcu.PanelComposer.Models.Model.Drawing>(Drawing);
                SelectedProject.Drawing = Drawing;
            }

            // upozorneni View, ze budeme cist
            ForceRead = DateTime.Now.Millisecond;

            // ulozime jiz ve spravnem poradi do DB
            SelectedProject.XamlTexture = Serializable;
            Repository.Commit();

            // ulozit do DB
            Navigate(PageNames.ProjectDetail);
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Loads the data.
        /// </summary>
        private void LoadData()
        {  
            // nacteme kolekci bodu polygonu
            PolyCollection = PointCollection.Parse(SelectedProject.BasePolygon);

            // pocet pater
            Floors = SelectedProject.Floors;
            Height = 50;

            Serializable = SelectedProject.XamlTexture ?? string.Empty;
        }

        #endregion
    }
}
